package com.enation.app.javashop.core.trade.order.service.impl;

import com.enation.app.javashop.core.client.goods.GoodsClient;
import com.enation.app.javashop.core.client.member.MemberAddressClient;
import com.enation.app.javashop.core.client.member.MemberClient;
import com.enation.app.javashop.core.goods.model.vo.CacheGoods;
import com.enation.app.javashop.core.goods.model.vo.GoodsSkuVO;
import com.enation.app.javashop.core.member.model.dos.Member;
import com.enation.app.javashop.core.member.model.dos.MemberAddress;
import com.enation.app.javashop.core.promotion.tool.model.enums.PromotionTypeEnum;
import com.enation.app.javashop.core.trade.TradeErrorCode;
import com.enation.app.javashop.core.trade.cart.model.vo.*;
import com.enation.app.javashop.core.trade.cart.service.CartReadManager;
import com.enation.app.javashop.core.trade.order.model.dto.OrderDTO;
import com.enation.app.javashop.core.trade.order.model.vo.CheckoutParamVO;
import com.enation.app.javashop.core.trade.order.model.vo.ConsigneeVO;
import com.enation.app.javashop.core.trade.order.model.vo.TradeVO;
import com.enation.app.javashop.core.trade.order.service.*;
import com.enation.app.javashop.framework.context.UserContext;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.exception.NoPermissionException;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.security.model.Buyer;
import com.enation.app.javashop.framework.util.DateUtil;
import com.enation.app.javashop.framework.util.JsonUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 交易业务类
 *
 * @author Snow create in 2018/4/8
 * @version v2.0
 * @since v7.0.0
 */
@Service
public class TradeManagerImpl implements TradeManager {
    protected final Log logger = LogFactory.getLog(this.getClass());

    @Autowired
    @Qualifier("tradeDaoSupport")
    private DaoSupport daoSupport;

    @Autowired
    private CheckoutParamManager checkoutParamManager;

    @Autowired
    private CartReadManager cartReadManager;

    @Autowired
    private ShippingManager shippingManager;

    @Autowired
    private GoodsClient goodsClient;


    @Autowired
    private TradeSnCreator tradeSnCreator;

    @Autowired
    private MemberAddressClient memberAddressClient;

    @Autowired
    private MemberClient memberClient;

    @Autowired
    private TradeIntodbManager tradeIntodbManager;

    @Override
    public TradeVO createTrade() {

        //下单前检测
        this.checkTrade();

        //创建订单
        TradeVO tradeVO = this.innerCreateTrade();

        //订单入库
        this.tradeIntodbManager.intoDB(tradeVO);

        return tradeVO;
    }


    @Override
    @Transactional(value = "tradeTransactionManager", propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void updatePrice(String tradeSn, Double tradePrice, Double discountPrice) {
        String sql = "update es_trade set total_price=?,discount_price=? where trade_sn=?";
        this.daoSupport.execute(sql, tradePrice, discountPrice, tradeSn);
    }

    /**
     * 下单前的检测<br>
     * 检测的内容：（以下有一条出现问题，则不予许下单）<br>
     * 1、检测商品的库存是否超卖
     * 2、检测商品参与的活动是否已经超期
     * 3、检测价格：重新计算一遍价格是否和redis中存储的价格相同。
     *
     * @return 返回true则为允许下单，false则为检测有问题。
     */
    @SuppressWarnings("unchecked")
    private boolean checkTrade() {

        //读取结算参数
        CheckoutParamVO param = checkoutParamManager.getParam();

        Buyer buyer = UserContext.getBuyer();
        if (buyer == null) {
            throw new NoPermissionException("您的会话已经失效，请重新登陆再创建订单");
        }

        CartView cartView = this.cartReadManager.getCheckedItems();

        //已选中结算的商品
        List<CartVO> cartList = cartView.getCartList();

        //1、检测购物车是否为空
        if (cartList == null || cartList.isEmpty()) {
            throw new ServiceException(TradeErrorCode.E452.code(), "购物车为空");
        }

        //验证后存在商品问题的集合
        List<Map> goodsErrorList = new ArrayList();
        //验证后存在促销活动问题的集合
        List<Map> promotionErrorList = new ArrayList();

        //验证收货地址
        MemberAddress memberAddress = this.memberAddressClient.getModel(param.getAddressId());
        if (memberAddress == null) {
            throw new ServiceException(TradeErrorCode.E452.code(), "请填写收货地址");
        }

        Integer areaId = memberAddress.getCountyId();

        //2、筛选不在配送区域的商品
        List<CacheGoods> list = this.shippingManager.checkArea(cartList, areaId);
        if (list.size() > 0) {
            for (CacheGoods goods : list) {
                Map errorMap = new HashMap(16);
                errorMap.put("name", goods.getGoodsName());
                errorMap.put("image", goods.getThumbnail());
                goodsErrorList.add(errorMap);
            }
            throw new ServiceException(TradeErrorCode.E461.code(), "商品不在配送区域", goodsErrorList);
        }


        boolean flag = true;
        //遍历购物车集合
        for (CartVO cartVO : cartList) {

            List<CartSkuVO> skuList = cartVO.getSkuList();

            for (CartSkuVO cartSkuVO : skuList) {
                Map errorMap = new HashMap(16);
                errorMap.put("name", cartSkuVO.getName());
                errorMap.put("image", cartSkuVO.getGoodsImage());

                Integer skuId = cartSkuVO.getSkuId();
                GoodsSkuVO skuVO = this.goodsClient.getSkuFromCache(skuId);

                //检测商品是否存在
                if (skuVO == null) {
                    goodsErrorList.add(errorMap);
                    continue;
                }

                //检测商品的上下架状态
                if (skuVO.getMarketEnable() != null && skuVO.getMarketEnable().intValue() != 1) {
                    goodsErrorList.add(errorMap);
                    continue;
                }

                //检测商品的删除状态
                if (skuVO.getDisabled() != null && skuVO.getDisabled().intValue() != 1) {
                    goodsErrorList.add(errorMap);
                    continue;
                }

                Integer goodsId = skuVO.getGoodsId();
                CacheGoods goodsVo = this.goodsClient.getFromCache(goodsId);
                if (goodsVo.getIsAuth() == 0 || goodsVo.getIsAuth() == 3) {
                    goodsErrorList.add(errorMap);
                    continue;
                }

                //读取此产品的可用库存数量
                int enableQuantity = skuVO.getEnableQuantity();
                //此产品将要购买的数量
                int num = cartSkuVO.getNum();

                //如果将要购买的产品数量大于redis中的数量，则此产品不能下单
                if (num > enableQuantity) {
                    flag = false;
                    goodsErrorList.add(errorMap);
                    continue;
                }

                //此商品参与的单品活动
                List<CartPromotionVo> singlePromotionList = cartSkuVO.getSingleList();
                if (!singlePromotionList.isEmpty()) {
                    for (CartPromotionVo promotionGoodsVO : singlePromotionList) {

                        // 默认参与的活动 && 非不参与活动的状态
                        if (promotionGoodsVO.getIsCheck().intValue() == 1 && !promotionGoodsVO.getPromotionType().equals(PromotionTypeEnum.NO.name())) {
                            //当前活动的失效时间
                            long entTime = promotionGoodsVO.getEndTime();

                            //当前时间
                            long currTime = DateUtil.getDateline();

                            //如果当前时间大于失效时间，则此活动已经失效了，不能下单
                            if (currTime > entTime) {
                                flag = false;
                                promotionErrorList.add(errorMap);
                                continue;
                            }
                        }

                    }
                }

                //此商品参与的组合活动
                List<CartPromotionVo> groupPromotionList = cartSkuVO.getGroupList();
                if (!groupPromotionList.isEmpty()) {
                    for (CartPromotionVo cartPromotionGoodsVo : groupPromotionList) {
                        //当前活动的失效时间
                        long entTime = cartPromotionGoodsVo.getEndTime();

                        //当前时间
                        long currTime = DateUtil.getDateline();

                        //如果当前时间大于失效时间，则此活动已经失效了，不能下单
                        if (currTime > entTime) {
                            flag = false;

                            promotionErrorList.add(errorMap);
                            continue;
                        }
                    }
                }
            }

        }

        if (!goodsErrorList.isEmpty()) {
            throw new ServiceException(TradeErrorCode.E452.code(), "抱歉，您以下商品所在地区无货", JsonUtil.objectToJson(goodsErrorList));
        }

        if (!promotionErrorList.isEmpty()) {
            throw new ServiceException(TradeErrorCode.E452.code(), "抱歉，您以下商品所参与活动已失效", JsonUtil.objectToJson(promotionErrorList));
        }

        //读取订单的总交易价格信息
        PriceDetailVO detailVO = cartView.getTotalPrice();

        //此交易需要扣除用户的积分
        int point = detailVO.getExchangePoint();

        Member member = this.memberClient.getModel(buyer.getUid());
        int consumPoint = member.getConsumPoint();

        //如果用户可使用的消费积分小于 交易需要扣除的积分时，则不能下单
        if (consumPoint < point) {
            throw new ServiceException(TradeErrorCode.E452.code(), "您可使用的消费积分不足,请返回购物车修改商品");
        }

        return flag;
    }

    /**
     * 创建订单
     *
     * @return
     */
    private TradeVO innerCreateTrade() {

        Buyer buyer = UserContext.getBuyer();

        CheckoutParamVO param = checkoutParamManager.getParam();
        Assert.notNull(param.getAddressId(), "必须选择收货地址");
        Assert.notNull(param.getPaymentType(), "必须选择支付方式");

        CartView cartView =this.cartReadManager.getCheckedItems();
        List<CartVO> cartList = cartView.getCartList();
        MemberAddress address = this.memberAddressClient.getModel(param.getAddressId());

        //收货人
        ConsigneeVO consignee = new ConsigneeVO();
        consignee.setConsigneeId(address.getAddrId());
        consignee.setAddress(address.getAddr());

        consignee.setProvince(address.getProvince());
        consignee.setCity(address.getCity());
        consignee.setCounty(address.getCounty());
        consignee.setTown(address.getTown());

        consignee.setProvinceId(address.getProvinceId());
        consignee.setCityId(address.getCityId());
        consignee.setCountyId(address.getCountyId());
        if (address.getTownId() != null) {
            consignee.setTownId(address.getTownId());
        }
        consignee.setMobile(address.getMobile());
        consignee.setTelephone(address.getTel());
        consignee.setName(address.getName());


        String tradeNo = tradeSnCreator.generateTradeSn();
        TradeVO tradeVO = new TradeVO();

        //收货人
        tradeVO.setConsignee(consignee);

        //效果编号
        tradeVO.setTradeSn(tradeNo);

        //支付类型
        tradeVO.setPaymentType(param.getPaymentType().value());

        //会员信息
        tradeVO.setMemberId(buyer.getUid());
        tradeVO.setMemberName(buyer.getUsername());
        List<OrderDTO> orderList = new ArrayList<OrderDTO>();

        //订单创建时间
        long createTime = DateUtil.getDateline();

        List<CouponVO> couponVOS = new ArrayList<>();
        //生成订单
        for (CartVO cart : cartList) {

            //生成订单编号
            String orderSn = tradeSnCreator.generateOrderSn();

            //购物信息
            OrderDTO order = new OrderDTO(cart);

            //创建时间
            order.setCreateTime(createTime);

            //购买的会员信息
            order.setMemberId(buyer.getUid());
            order.setMemberName(buyer.getUsername());
            order.setTradeSn(tradeNo);
            order.setSn(orderSn);
            order.setConsignee(consignee);

            //配送方式 这个参数暂时无效
            order.setShippingId(0);

            //支付类型
            order.setPaymentType(param.getPaymentType().value());
            //发票
            order.setNeedReceipt(0);
            if (param.getReceipt() != null) {
                order.setNeedReceipt(1);
            }
            order.setReceiptVO(param.getReceipt());
            //收货时间
            order.setReceiveTime(param.getReceiveTime());

            //订单备注
            order.setRemark(param.getRemark());

            //订单来源
            order.setClientType(param.getClientType());

            //订单价格
            order.getPrice().reCountDiscountPrice();

            if (logger.isDebugEnabled()) {
                logger.debug("订单["+order.getSn()+"]的price:");
                logger.debug(order.getPrice());
            }


            order.setNeedPayMoney(order.getPrice().getTotalPrice());

            order.setOrderPrice(order.getPrice().getTotalPrice());

            order.setGoodsNum(cart.getSkuList().size());

            orderList.add(order);

            if(cart.getCouponList()!=null&&cart.getCouponList().size()>0){
                for (CouponVO couponVO: cart.getCouponList()) {
                    if(couponVO.getSelected()==1){
                        couponVOS.add(couponVO);
                    }
                }
            }


        }

        //读取结算价格
        PriceDetailVO paymentDetail = cartView.getTotalPrice();
        paymentDetail.reCountDiscountPrice();
        if (logger.isDebugEnabled()) {
            logger.debug("生成TradeVO时price为");
            logger.debug(paymentDetail);
        }
        //交易价格
        tradeVO.setPriceDetail(paymentDetail);

        tradeVO.setOrderList(orderList);


        tradeVO.setCouponList(couponVOS);
        return tradeVO;
    }

}
